﻿using DataLayer;
using DataLayer.Model;
using FitbitAPI;
using FitbitAPI.Models;
using FitbitManager.WrapperLibrary;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FitbitManager.Subscripters
{
    public class ConsumerManager
    {
        public void UpdateFitbitDataReceived(string responseText)
        {
            UnitOfWork repository = UnitOfWork.CreateIntance();

            var updates = WrapperSubscriptionManager.GetUpdatesResources(responseText)
                                .Where(u => u.CollectionType == APICollectionType.activities);

            foreach (var updatedResource in updates)
            {
                UpdateFitbitDataActivity(updatedResource);
            }

            repository.Commit();
        }

        private void UpdateFitbitDataActivity(UpdatedResource updateResource)
        {
            FitbitAccount fitbitAccount;

            UnitOfWork repository = UnitOfWork.CreateIntance();

            fitbitAccount = repository.FitbitAccountRepository.GetByOwnerId(updateResource.OwnerId);


            if (fitbitAccount != null)
            {
                WrapperFitbitClient client = WrapperFitbitClient.CreateFitbitClient(fitbitAccount.AccessToken, fitbitAccount.AccessSecret);

                LogManager.AddLogAlert("INFO: Nofitication from " + fitbitAccount.UserName + " of type " + Enum.GetName(typeof(APICollectionType), updateResource.CollectionType) + " received. Owner=" + updateResource.OwnerId);

                Activity resource = client.GetDayActivity(updateResource.Date);

                FitbitData data = fitbitAccount.FitbitDatas.FirstOrDefault(x => x.Date == updateResource.Date);

                if (data == null)
                {
                    data = new FitbitData()
                    {
                        Date = updateResource.Date,
                        IdFitbitAccount = fitbitAccount
                    };
                }

                data.Steps = resource.Summary.Steps;
                data.Floors = resource.Summary.Floors;
                data.Distance = (float)Math.Round(resource.Summary.Distances.First(x => x.Activity.ToLowerInvariant() == "total").Distance, 2);

                if (data.Steps != 0 || data.Floors != 0 || data.Distance != 0)
                {
                    fitbitAccount.FitbitDatas.Add(data);
                    repository.Commit();
                }
            }
            else
            {
                //The user had been deleted from DB, but the application is still subscribed to his changes!
                //To avoid this situation, the users to be removed will be marked in DB. And then, the manager will delete at first the subscription and later the user.
                LogManager.AddLogAlert("ERROR: Nofitication from a unknown user received. Owner=" + updateResource.OwnerId);
            }
        }
    }
}
